home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 5 / BOOZ_MAC / BOOZ_2 / BOOZ.C < prev    next >
C/C++ Source or Header  |  1992-07-19  |  7KB  |  270 lines

  1. #define  VERSION  "Version 2.0 (1991/07/07)\n"
  2.  
  3. /* booz.c -- small, memory-efficient zoo archive extractor/lister.
  4. This file is public domain.
  5.  
  6.                                     -- Rahul Dhesi 1991/07/07
  7. */
  8.  
  9. #include "booz.h"
  10. #include "zoo.h"
  11. #include <stdio.h>
  12.  
  13. #ifdef MAC
  14. #include <console.h>
  15. #endif
  16.  
  17. main(argc,argv)
  18. register int argc;
  19. register char **argv;
  20. {
  21.    char *p;
  22.    static char usage[]=
  23.       "Usage:  booz {lxt} archive[.zoo] [ file ... ]\n";
  24.  
  25. #ifdef MAC
  26.     static char  **marc;
  27.     marc = argv;
  28.     argc = ccommand(&marc);
  29.     argv = marc;
  30. #endif
  31.  
  32.    if (argc < 3) {
  33.       putstr ("Public domain zoo archive extractor/lister by Rahul Dhesi\n");
  34.       putstr (VERSION);
  35.       putstr (usage);
  36.       putstr ("l = list, x = extract, t = test\n");
  37.       exit (1);
  38.    }
  39.  
  40.    gentab();        /* generate CRC table */
  41.  
  42.    p = argv[1];
  43.    if (*p == 'L')
  44.       *p = 'l';
  45.    if (*p == 'X')
  46.       *p = 'x';
  47.    if (*p == 'T')
  48.       *p = 't';
  49.    if (*p != 'l' && *p != 'x' && *p != 't') {
  50.       putstr (usage);
  51.       exit (1);
  52.    }
  53.       oozext (argv[2], p, argc - 3, &argv[3]);
  54.    exit (0);
  55. }
  56.  
  57. /**********************/
  58. /* putstr()
  59. This function prints a string to standard output without using
  60. printf(). If a null string, nothing is printed.  */
  61.  
  62. int putstr (str)
  63. register char *str;
  64. {
  65.    register int count;
  66.    if (str == NULL)
  67.       return;
  68.    count = strlen(str);
  69.    if (count != 0)
  70.       fwrite (str, 1, count, stdout);
  71. }
  72.  
  73. /**********************/
  74. /* prterror()
  75. Prints an error message.  The first character controls the severity
  76. of the error and the result.
  77.  
  78.    'm'   informative message
  79.    'w'   warning     -- execution continues
  80.    'e'   error       -- execution continues
  81.    'f'   fatal error -- program exits
  82. */
  83.  
  84. int prterror (level, a, b, c)
  85. int level;
  86. char *a, *b, *c;
  87.  
  88. {
  89.  
  90. #ifdef DEBUG
  91.    {
  92.       char tmp[2];
  93.       tmp[0] = level & 0x7f;
  94.       tmp[1] = '\0';
  95.       putstr ("prterror:  level = ");
  96.       putstr (tmp);
  97.       putstr ("\n");
  98.    }
  99. #endif
  100.  
  101.    switch (level & 0x7f) {
  102.       case 'm': break;
  103.       case 'w': putstr ("WARNING:  "); break;
  104.       case 'e': putstr ("ERROR:  "); break;
  105.       case 'f': putstr ("FATAL:  "); break;
  106.       default: prterror ('f', "Internal error\n", ((char *) 0), ((char *) 0));
  107.    }
  108.    putstr (a);
  109.    putstr (b);
  110.    putstr (c);
  111.  
  112.    if (level == 'f')       /* and abort on fatal error 'f' but not 'F' */
  113.       exit (1);
  114. }
  115.  
  116. /*************
  117. This function copies 'count' characters from the source file to the
  118. destination. Function return value is 0 if no error, 2 if write error,
  119. and 3 if read error.  
  120.  
  121. The global variable 'crccode' is updated.
  122. */
  123. extern char out_buf_adr[];
  124.  
  125. int getfile(infile, outfile, count)
  126. FILE *infile;
  127. FILE *outfile;
  128. long count;
  129. {
  130.    register int how_much;
  131.  
  132.    while (count > 0) {
  133.       if (count > MEM_BLOCK_SIZE)
  134.          how_much = MEM_BLOCK_SIZE;
  135.       else
  136.          how_much = count;
  137.       count -= how_much;
  138.       if (fread (out_buf_adr, 1, how_much, infile) != how_much)
  139.          return (3);
  140.       addbfcrc (out_buf_adr, how_much);
  141.       if (outfile != NULL &&
  142.             fwrite (out_buf_adr, 1, how_much, outfile) != how_much)
  143.          return (2);
  144.    }
  145.    return (0);
  146. }
  147.  
  148. int needed (fname, argc, argv)
  149. char *fname;
  150. int argc;
  151. char *argv[];
  152. {
  153.    register int i;
  154.    if (argc == 0)
  155.       return (1);
  156.    for (i = 0; i < argc; i++) {
  157.       if (match (fname, argv[i]))
  158.          return (1);
  159.    }
  160.    return (0);
  161. }
  162.  
  163. /***********************/
  164. /*
  165. match() compares a pattern with a string.  Wildcards accepted in
  166. the pattern are:  "*" for zero or more arbitrary characters;  "?"
  167. for any one characters.  Unlike the MS-DOS wildcard match, "*" is
  168. correctly handled even if it isn't at the end of the pattern. ".'
  169. is not special.
  170.  
  171. Originally written by Jeff Damens of Columbia University Center for
  172. Computing Activities.  Taken from the source code for C-Kermit version
  173. 4C.
  174. */
  175.  
  176. int match (string, pattern) 
  177. register char *string, *pattern;
  178. {
  179.    char *psave,*ssave;        /* back up pointers for failure */
  180.    psave = ssave = ((char *) 0);
  181.    while (1) {
  182.       for (; *pattern == *string; pattern++,string++)  /* skip first */
  183.          if (*string == '\0') 
  184.             return(1);                          /* end of strings, succeed */
  185.       if (*string != '\0' && *pattern == '?') {
  186.          pattern++;                             /* '?', let it match */
  187.          string++;
  188.       } else if (*pattern == '*') {             /* '*' ... */
  189.          psave = ++pattern;                     /* remember where we saw it */
  190.          ssave = string;                        /* let it match 0 chars */
  191.       } else if (ssave != ((char *) 0) && *ssave != '\0') {   /* if not at end  */
  192.          /* ...have seen a star */
  193.          string = ++ssave;                      /* skip 1 char from string */
  194.          pattern = psave;                       /* and back up pattern */
  195.       } else 
  196.          return(0);                             /* otherwise just fail */
  197.    }
  198. }
  199.  
  200. int memerr()
  201. {
  202.    prterror ('f', "Ran out of memory\n", (char *) 0, (char *) 0);
  203. }
  204.  
  205. /* cfactor() calculates the compression factor given a directory entry */
  206. int cfactor (org_size, size_now)
  207. long org_size, size_now;
  208. {
  209.    register int size_factor;
  210.  
  211.    while (org_size > 10000) { /* avoid overflow below */
  212.       org_size = org_size >> 4;
  213.       size_now = size_now >> 4;
  214.    }
  215.    if (org_size == 0)         /* avoid division by zero */
  216.       size_factor = 0;
  217.    else {
  218.       size_factor = 
  219.          (
  220.             (1000 * 
  221.                (org_size - size_now)
  222.             ) / org_size + 5
  223.          ) / 10;
  224.    }
  225.    return (size_factor);
  226. }
  227.  
  228. /******
  229. Function itoa() converts a positive long integer into a text string of
  230. digits.  The buffer pointer buf must point to a buffer to receive the
  231. digit string.  The digit string is stored right justified in the
  232. buffer with leading blanks.  If the supplied number is negative, or if
  233. overflow occurs, a single '*' is returned.
  234. */
  235.  
  236. char *itoa (pad_ch, n, buf, buflen)
  237. char pad_ch;                  /* leading pad character */
  238. long n;                       /* positive long int to convert */
  239. char *buf;                    /* buffer to receive digit string */
  240. int buflen;                   /* length of buffer */
  241. {
  242.    char *p;
  243.    int i;
  244.    for (i = 0;  i < buflen;  i++)         /* fill buffer with pad char */
  245.       buf[i] = pad_ch;
  246.    p = buf + buflen - 1;
  247.    *p-- = '\0';                           /* ensure null termination */
  248.    i = buflen - 1;
  249.    for (;;) {
  250.       if (n < 0) {                        /* can't handle negative n */
  251.          goto overflow;
  252.       } else {
  253.          *p-- = (int) (n % 10) + '0';     /* store a converted digit */
  254.          n = n / 10;
  255.          i--;
  256.          if (n == 0 || i == 0)
  257.             break;
  258.       } /* end of else of if (n < 0) */
  259.    } /* end while (buflen > 0) */
  260.    if (n != 0)                            /* buffer overflow */
  261.       goto overflow;
  262.    return (buf);
  263.  
  264. overflow:                                 /* bad value filled with stars */
  265.    for (i = 0; i < buflen; i++)
  266.       buf[i] = '*';
  267.    buf[buflen-1] = '\0';
  268.    return (buf);
  269. }
  270.